import Dep from './Dep'
var uid = 0;

export default class Watcher {
  constructor(target, expression, callback) {    
    console.log('我是Watcher 构造器')
    this.id = uid++
    this.target = target 
    this.getter = parsePath(expression) 
    this.callback = callback
    this.value = this.get() 
  }
  get() {
    // 进入依赖收集阶段。让全局的Dep.target设置为当前Watcher的实例，在访问data的属性时，就可以在defineReactive的get方法中触发依赖收集。
    // 进入依赖收集阶段。让全局的Dep.target设置为Watcher本身，那么就是进入依赖收集阶段
    Dep.target = this  // 触发依赖收集：先把自己设为"当前订阅者"
    const obj = this.target
    var value;
    // 只要能找到就一直找
    try {
      value = this.getter(obj)
    } finally {
      Dep.target = null
    }
    return value;
  }
  update () {
    this.run()
  }
  run () {
    this.getAndInvoke(this.callback)
  }
  // 比较当前值和之前值，变化了再触发。
  getAndInvoke(cb) {
    const value = this.get() // 获取当前值，为最新的值
    // this.value - 修改前的值。
    if (value !== this.value || typeof value === 'object') {
      const oldValue = this.value
      this.value = value
      // 触发更新视图
      cb.call(this.target, value, oldValue)
    }
  }
}


// 从给定的data的路径表达式，得到这个data最终的值。
function parsePath(path) {
  var segments = path.split('.');
  return function(obj) {
    for (var i=0; i<segments.length; i++) {
      if (!obj) return
      obj = obj[segments[i]];
    }
    return obj 
  }
} 